<template>
	<div class="flex-center w-full refresh-select-wrapper">
		<el-select
			:class="`flex-grow ${showButton ? 'mr10' : ''}`"
			v-model="selectValue"
			v-bind="$attrs"
			v-selectLoadMore:[$attrs]="selectLoadMore"
			:remote-method="remoteMethod"
			@change="onChange"
		>
			<el-option
				v-for="item in optionData"
				:key="item[optionMap.value]"
				:label="typeof optionMap.label == 'function' ? optionMap.label(item) : item[optionMap.label]"
				:value="item[optionMap.value]"
			/>
		</el-select>
		<el-button v-if="showButton" type="primary" link @click="onCreate">新建</el-button>
		<el-divider v-if="showButton" direction="vertical" />
		<el-button v-if="showButton" type="primary" link @click="refresh">刷新</el-button>
	</div>
</template>
<script setup lang="ts" name="refreshSelect">
import { nextTick, watch, ref, onBeforeMount } from 'vue';
import { useRouter } from 'vue-router';
const router = useRouter();

interface Props {
	modelValue: any; // 搜索参数
	api?: (params?: any) => Promise<any>;
	apiParams?: any;
	link?: string;
	showButton?: boolean;
	optionMap: { label: string | ((data: any) => string); value: string };
	dataFormat?: (data: any) => void;
	initChange?: (data: any) => void;
}
// // 默认值
let props = withDefaults(defineProps<Props>(), {
	modelValue: '',
	link: '',
	showButton: true,
	apiParams: {},
	optionMap: () => ({
		label: 'label',
		value: 'value',
	}),
});

const emit = defineEmits(['update:modelValue', 'change']);
const optionData = ref<any[]>([]);
const selectValue = ref<any>();

const pagation = {
	page: 1,
	size: 10,
};

let hasMore = true;

const onChange = (val: any) => {
	const target = optionData.value.find((item) => {
		return item[props.optionMap.value] === val;
	});
	emit('update:modelValue', val);
	emit('change', target);
};

watch(
	() => props.modelValue,
	(val) => {
		if (!selectValue.value && val && props.initChange) {
			const target = optionData.value.find((item) => {
				return item[props.optionMap.value] === val;
			});
			props.initChange(target);
		}
		if (selectValue.value != val) {
			selectValue.value = val;
		}
	},
	{
		deep: true,
		immediate: true,
	}
);

const onCreate = () => {
	let routeUrl = router.resolve({
		path: props.link,
	});
	window.open(routeUrl.href, '_blank');
};

const remoteMethod = (query: string) => {
	pagation.page = 1;
	optionData.value = [];
	getOptionData(query);
};

const getOptionData = async (query?: string) => {
	if (props.api) {
		const params: any = props.apiParams;
		if (query) {
			params[params.queryKey] = query;
		} else {
			delete params[params.queryKey];
		}

		const res = await props.api({ ...pagation, ...params });

		let data = res.data.records || res.data || [];
		if (props.dataFormat) {
			data = props.dataFormat(data);
		}
		if (data.length < pagation.size) {
			hasMore = false;
		} else {
			hasMore = true;
		}
		optionData.value = [...optionData.value, ...data];
	}
};

const refresh = () => {
	pagation.page = 1;
	optionData.value = [];
	getOptionData();
};

const selectLoadMore = () => {
	if (!hasMore) {
		return;
	}
	pagation.page++;
	getOptionData();
};

onBeforeMount(() => {
	getOptionData();
});
</script>
<style lang="scss" scoped>
.refresh-select-wrapper {
	width: 100%;
}
</style>
